﻿using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using XbsWebAPI.Application;
using XbsWebAPI.Application.SystemAdmin;
using XbsWebAPI.Application.SystemAdmin.Dtos;
using XbsWebAPI.EntityFrameworkCore.Entities;
using XbsWebAPI.MainHost.ViewModels;

namespace XbsWebAPI.MainHost.Controllers
{
    [ApiController]
    [Route("api/xbs_v1/[controller]")]
    public class SystemAccountController : Controller
    {
        private readonly UserManager<XbsAdminUser> _userManager;
        private readonly SignInManager<XbsAdminUser> _signInManager;
        private readonly IXbsAdminUserAppService _xbsAdminUserAppService;
        private readonly ISystemRoleAppService _systemRoleAppService;

        public SystemAccountController(UserManager<XbsAdminUser> userManager, SignInManager<XbsAdminUser> signInManager, IXbsAdminUserAppService xbsAdminUserAppService, ISystemRoleAppService systemRoleAppService)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _xbsAdminUserAppService = xbsAdminUserAppService;
            _systemRoleAppService = systemRoleAppService;
        }

        /// <summary>
        /// 注册账号
        /// </summary>
        /// <param name="model">注册对象</param>
        /// <returns></returns>
        [HttpPost, Route("[action]")]
        public async Task<ResultDto<object>> Register(RegiterViewModel model)
        {
            var result = new ResultDto<object>();
            if (ModelState.IsValid)
            {
                var user = new XbsAdminUser
                {
                    UserName = model.UserName,
                    Email = model.Email,
                    RoleId = model.RoleId
                };

                //username加入数据库
                var resultUser = await _userManager.CreateAsync(user, model.Password);
                if (resultUser.Succeeded)
                {
                    //await _signInManager.SignInAsync(user, isPersistent: false);
                    result.Message = "操作成功";
                    return result;
                }

                result.Message = "操作失败";
                result.Code = -1;
                var errors = new List<string>();
                foreach (var error in resultUser.Errors)
                {
                    errors.Add(error.Description);
                }
                result.Result = errors;

                return result;
            }

            result.Message = "模型验证失败，请重新填写";
            result.Code = -1;
            return result;
        }

        /// <summary>
        /// 登录账号
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost, Route("[action]")]
        public async Task<ResultDto<object>> Login(LoginViewModel model)
        {
            var result = new ResultDto<object>();
            if (ModelState.IsValid)
            {
                var resultUser = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false);
                if (resultUser.Succeeded)
                {
                    result.Message = "操作成功";
                    //登录成功，查询对应角色Id，展示相应权限
                    var user = await _userManager.FindByNameAsync(model.UserName);
                    var roleId = user.RoleId == null? Guid.Empty : user.RoleId.Value;
                    var role = _systemRoleAppService.GetSystemRoleById(roleId);
                    if (role != null)
                    {
                        result.Result = role.Result.SelectedMenus;
                    }
                    return result;
                }

                result.Message = "操作失败";
                result.Code = -1;
            }

            return result;
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("[action]")]
        public async Task<ResultDto<object>> Logout()
        {
            var result = new ResultDto<object>();
            try
            {
                await _signInManager.SignOutAsync();
                result.Message = "操作成功";
            }
            catch (System.Exception e)
            {
                result.Message = e.Message;
                result.Code = -1;
                return result;
            }

            return result;
        }

        /// <summary>
        /// 查询所有账号列表
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("[action]")]
        public ResultDto<List<ListAdminUserDto>> FindAllUsers()
        {
            var result = _xbsAdminUserAppService.FindAdminUsers();
            return result;
        }

        /// <summary>
        /// 查询单个账号
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet, Route("[action]")]
        public async Task<ResultDto<object>> FindUserById(string id)
        {
            var result = new ResultDto<object>();

            var model = await _userManager.FindByIdAsync(id);
            if (model == null)
            {
                result.Code = -1;
                result.Message = $"Id={id}用户不存在";
                return result;
            }

            var resultModel = new
            {
                Id = id,
                UserName = model.UserName,
                Email = model.Email,
                RoleId = model.RoleId,
            };

            result.Message = "操作成功";
            result.Result = resultModel;
            return result;
        }

        /// <summary>
        /// 编辑用户
        /// </summary>
        /// <param name="model">用户的对象</param>
        /// <returns></returns>
        [HttpPost, Route("[action]")]
        public async Task<ResultDto<string>> EditUser(EditViewModel model)
        {
            var result = new ResultDto<string>();

            var user = await _userManager.FindByIdAsync(model.Id);
            if (user == null)
            {
                result.Code = -1;
                result.Message = $"需要编辑的Id={model.Id}用户不存在";
                return result;
            }

            user.UserName = model.UserName;
            user.Email = model.Email;
            user.RoleId = model.RoleId;

            var resultUser = await _userManager.UpdateAsync(user);
            if (resultUser.Succeeded)
            {
                result.Message = "操作成功";
                return result;
            }

            result.Message = "操作失败";
            result.Code = -1;
            return result;
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户Id</param>
        /// <returns></returns>
        [HttpGet, Route("[action]")]
        public async Task<ResultDto<string>> DeleteUser(string id)
        {
            var result = new ResultDto<string>();

            var model = await _userManager.FindByIdAsync(id);
            if (model == null)
            {
                result.Code = -1;
                result.Message = $"Id={id}用户不存在";
                return result;
            }

            var resultUser = await _userManager.DeleteAsync(model);
            if (resultUser.Succeeded)
            {
                result.Message = "删除成功";
                return result;
            }

            result.Message = "操作失败";
            result.Code = -1;
            return result;
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("[action]")]
        public async Task<ResultDto<object>> ChangePassword(ChangePasswordViewModel model)
        {
            var result = new ResultDto<object>();
            var user = await _userManager.FindByIdAsync(model.Id);
            if (user == null)
            {
                result.Code = -1;
                result.Message = $"需要修改密码的Id={model.Id}用户不存在";
                return result;
            }
            var newUser = await _userManager.ChangePasswordAsync(user,model.OldPassword,model.NewPassword);
            if (newUser.Succeeded)
            {
                result.Message = "操作成功";
                return result;
            }

            result.Message = "操作失败";
            result.Code = -1;
            var errors = new List<string>();
            foreach (var error in newUser.Errors)
            {
                errors.Add(error.Description);
            }
            result.Result = errors;
            return result;
        }
    }
}
